# In this example we will see how we can use the python date and time libraries. This example may not be directly related to GUI
# development in PySide I am placing this file here for future reference while developing PySide applications.

from datetime import date
from datetime import time
from datetime import datetime
# Timedeltas: Used to perform mathematical operations on dates and times, e.g. calculating number of days till an event.
from datetime import timedelta
import calendar


def main():
    # DATE OBJECTS
    # Get today's date using the "today" method in the "date" class
    today = date.today()
    print("01. Today's date is ", today)
    
    # Print out the date's individual components
    print("02. Date Components: ", today.day, today.month, today.year)
     
    # Retrieve today's weekday (0 = Monday and 6 = Sunday)
    print("03. Today's weekday is ", today.weekday()) 
     
    ## DATETIME OBJECTS
    # Get today's date from the "datetime" class
    today = datetime.now()
    print("04. The current datetime is ", today)
     
    # Get the current time
    t = datetime.time(datetime.now())
    print("05. The current time is : ", t)
    
    # Weekday returns 0 (Monday) through 6 (Sunday)
    wd = date.weekday(today)
    # Days  start at 0 (Monday)
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
    print("06. Today is day number: %d   (0 for Monday)" % wd)
    print("07. Which is a " + days[wd])
    
    ## Format the date and time outputs using the a set of predefined string control codes
    now = datetime.now()
    
    ### DATE FORMATTING ###
    # %y / %Y - Year     %a / %A - Weekday     %b / %B - Month     %d - Day of Month
     
     # Full year with century
    print("08. Full year with century ", now.strftime("%Y"))
    
    # Abbreviated weekday, day of month,  full month, abbreviated year (without century) 
    print("09. Abb.  Weekday, Date,  Month name, Abb. Year (without century)", now.strftime("%a, %d %B , %y"))
    
    # %c - locale's date and time    %x - locale's date    %X - locale's time
    print("10. Locale's date and time ", now.strftime("%c"))
    print("11. Locale's date ", now.strftime("%x"))
    print("12. Locale's time ", now.strftime("%X"))
    
    ### Time Formatting ###
    # %I / %H - 12/24 Hour    %M - Minute    %S - Second    %p - Locale's AM/PM
    
    # 12-Hour : Minute : Second - AM/PM
    print("13. Time format 12 Hr: ", now.strftime("%I:%M:%S %p"))
    
    # 24-Hour : Minute
    print("14. Time format 24 Hr: ",now.strftime("%H:%M"))
    
    ### Time Deltas ###
    # Time delta is basically a span of time
    
    # Construct a basic time-delta and print it
    print("15. Time delta for 365 days, 5 hours and 1 minute: ", timedelta(days=365, hours=5, minutes=1))
    
    # Print today's date
    print("16. Today is: ", datetime.now()) 
    
    # Print today's date, one year from now
    print("17. One year from now, it'll be: ", datetime.now() + timedelta(days=365))

    # Time delta that uses more than one argument
    print("18. In two weeks and three days, it'll be: ", datetime.now() + timedelta(weeks=2, days=3))
    
    # Calculate the date one week ago
    t = datetime.now() - timedelta(weeks=1)
    s = t.strftime("%A %B %d, %Y")
    print("19. One week ago, it was: ", s)
    
    # How many days until April fool's day
    today = date.today()    # Get today's date
    afd = date(today.year, 4, 1)    # Get April Fool's day for the current year
    # Use comparison if the April Fool's day has already passed or not in the current year
    # If it has passed, use the replace() function to get the date for the next year
    if afd < today:
        # Note we are using the days property on the difference of dates.
        print("20. April Fool's day has already went by %d days ago" % (today - afd).days)
        afd = afd.replace(year = today.year + 1)    # If so, get the date for the next year
    # Now calculate the time until April Fool's day.
    time_to_afd = abs(afd - today)
    print("20. Days remaining till April Fool's day: ", time_to_afd.days) 
    
    ### CALENDERS ###
    # Create a plain text calendar
    c = calendar.TextCalendar(calendar.SUNDAY)
    str = c.formatmonth(2013, 1, 0, 0)
    print(str)
    
    # Create an HTML Formatted calendar
    hc = calendar.HTMLCalendar(calendar.SUNDAY)
    str = hc.formatmonth(2014, 1, 0)
    print(str)
    
    # Loop over the days of a month
    # Zeros mean that these days of the week is an overlapping month
    for i in c.itermonthdays(2014, 8):
        print(i)
    
    # The calendar module also provides useful utilities for the given locale, such as the names of days and months
    # in both full and abbreviated forms.
    for monthName in calendar.month_name:
        print(monthName)
    for dayName in calendar.day_name:
        print(dayName)
    
    # Calculate days based on a rule. For example consider a team meeting on the first Friday of every month.
    # To figure out what days that would be for each month, we can use the following script
    for m in range(1, 13):
        # returns an array of weeks that represent a month
        cal = calendar.monthcalendar(2014, m)
        # The first Friday has to be within the first two weeks
        weekone = cal[0]
        weektwo = cal[1]
        if weekone[calendar.FRIDAY] !=0:
            meetingDay = weekone[calendar.FRIDAY]
        else:
            # If the Friday is not in the first week, then it must be in the second week
            meetingDay = weektwo[calendar.FRIDAY]
        print("%10s %2d" % (calendar.month_name[m], meetingDay))
        
         
if __name__ == "__main__":
    main()